// Copyright (c) [Year] [name of copyright holder]
// [Software Name] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2. 
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2 
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  
// See the Mulan PSL v2 for more details.

/*!
 * \autor captainpeng
 * \date 2019-1-15
 * \update 2019-6-10
 * \version 1.0
 * \copyright
 */

#ifndef MY_TYPEREMOVE_HPP
#define MY_TYPEREMOVE_HPP

#include<type_traits>

namespace my{
    //移除指针中的值的const volatile
    
    template<typename T>
    using rm_ptrcv_t=std::add_pointer_t<
	std::remove_cv_t<std::remove_pointer_t<T>>>;

    //移除类型的引用和const volatile
    //但是并不会移除const volatitle int *的
    //因为他们修饰的并非指针而是他们的值
    template<typename T>
    using rm_refcv_t=std::remove_cv_t<std::remove_reference_t<T> >;

    //整合上面，用于清除所有ref和const volatile
    // template<typename T,bool value=std::is_pointer<T>::value>
    // class rm_all_refcv;

    // template<typename T>
    // class rm_all_refcv<T,true>{
    // public:
    // 	using type=rm_ptrcv_t<T>;
    // };

    // template<typename T>
    // class rm_all_refcv<T,false>{
    // private:
    // 	using rmCvrefType=rm_refcv_t<T>;
    // public:
    // 	using type=typename std::conditional<
    // 	std::is_pointer<rmCvrefType>::value,
    // 	rm_ptrcv_t<rmCvrefType>,
    // 	rmCvrefType
    // 	>::type;
    // };

    // 2019-6-10 发现错误
    // 原来的去除所有的 cvref 发现不能满足如下:
    // print_is_same<int **,my::rm_all_refcv_t<int const * const *>>()
    // 所以修改成递归循环指针的指针直到完整去除
    
    template<typename T,bool value=std::is_pointer<T>::value>
    class rm_all_refcv;

    template<typename T>
    class rm_all_refcv<T,true>{
    public:
	using type=std::add_pointer_t<typename rm_all_refcv<std::remove_pointer_t<T>>::type>;
    };

    template<typename T>
    class rm_all_refcv<T,false>{
    public:
	using type=rm_refcv_t<T>;
    };

    //rm_all_cvref 的using帮助类型
    template<typename T>
    using rm_all_refcv_t=typename rm_all_refcv<T>::type;

					  
}

#endif
